<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>光照效果</title>
  <script src="../scripts/build/three.js"></script>
  <script src="../scripts/OrbitControls.js"></script>
</head>

<body>
  <script>
    window.onload = function () {
      init();
    }

    function init() {
      /* 创建3D场景 */
      let scene = new THREE.Scene();
      /* 构建图形  --start-- */
      let react = addBoxGeometry();
      let sphere = addSphereGeometry();
      let cylinder = addCylinderGeometry();
      let octahedron = addOctahedronGeometry();
      let dodecahedron = addDodecahedronGeometry();
      let icosahedron = addIcosahedronGeometry();
      /* 构建图形  --end-- */
      /* 同时绘制多个几何体
       * 1 创建几何体和材质对象。
       * 2 将两个对象作为参作为构造函数Mesh()的参数，然后创建一个网络模型。
       * 3 使用场景对象scene方法add将网络模型添加至场景中。
       * threejs的几何体默认位于场景世界坐标的（0,0,0），所以绘制几何体的时候，主要是他们的位置设置。
       */
      let material1 = createMaterial();
      let mesh1 = createMesh(react, material1);
      scene.add(mesh1);
      let material2 = createPhongMaterialMesh();
      let mesh2 = createMesh(sphere, material2);
      mesh2.translateX(100);
      scene.add(mesh2);
      let material3 = createMaterial();
      let mesh3 = createMesh(cylinder, material3);
      mesh3.translateY(120);
      scene.add(mesh3);
      let material4 = createMaterial();
      let mesh4 = createMesh(octahedron, material4);
      scene.add(mesh4);
      mesh4.translateZ(120);
      let material5 = createMaterial();
      let mesh5 = createMesh(dodecahedron, material5);
      mesh5.position.set(300, 150, 150);
      scene.add(mesh5);
      let material6 = createMaterial();
      let mesh6 = createMesh(icosahedron, material6);
      mesh6.position.set(150, 180, 50);
      scene.add(mesh6);
      /* 添加调试辅助坐标 */
      let axisHelper = new THREE.AxisHelper(250);
      scene.add(axisHelper);

      /**
       * 光源设置
       */
      // 点光源
      let point = new THREE.PointLight(0xffffff);
      point.position.set(400, 200, 300); //点光源位置
      scene.add(point); //点光源添加到场景中
      let point1 = new THREE.PointLight(0xffffff);
      point1.position.set(-400, -200, -300); //点光源位置
      scene.add(point1); //点光源添加到场景中
      //环境光源
      let point2 = new THREE.AmbientLight(0x444444);
      //point.position.set(400, 200, 300); //点光源位置
      scene.add(point2); //点光源添加到场景中
      //环境光
      let ambient = new THREE.AmbientLight(0x444444);
      scene.add(ambient);
      // 平行光
      var directionalLight = new THREE.DirectionalLight( 0x444444, 0.5 );
      scene.add( directionalLight );
      /**
       * 相机设置
       */
      let width = window.innerWidth; //窗口宽度
      let height = window.innerHeight; //窗口高度
      let k = width / height; //窗口宽高比
      let s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(200, 300, 200); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      /**
       * 创建渲染器对象
       */
      let renderer = new THREE.WebGLRenderer({
        antialias: true
      });
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
      //执行渲染操作   指定场景、相机作为参数
      //renderer.render(scene, camera);
      function render() {
        renderer.render(scene, camera); //执行渲染操作
      }
      render();
      var controls = new THREE.OrbitControls(camera, renderer.domElement); //创建控件对象
      controls.addEventListener('change', render); //监听鼠标、键盘事件

    }
    /* 创建标准几何体 */
    function addBoxGeometry(x = 100, y = 100, z = 100) {
      let geometry = new THREE.BoxGeometry(x, y, z);
      return geometry;
    }
    /* 创建球体 */
    function addSphereGeometry(r = 60, Longitude = 40, latitude = 40) {
      let sphere = new THREE.SphereGeometry(r, Longitude, latitude);
      return sphere;
    }
    /* 创建圆柱体 */
    function addCylinderGeometry(tr = 50, br = 50, height = 100, splice = 25) {
      let cylinder = new THREE.CylinderGeometry(tr, br, height, splice);
      return cylinder;
    }
    /* 创建正八面体 */
    function addOctahedronGeometry(r = 50) {
      let octahedron = new THREE.OctahedronGeometry(r);
      return octahedron;
    }
    /* 创建正十二面体 */
    function addDodecahedronGeometry(r = 50) {
      let Dodecahedron = new THREE.DodecahedronGeometry(r);
      return Dodecahedron;
    }
    /* 创建正二十面体 */
    function addIcosahedronGeometry(r = 50) {
      let icosahedron = new THREE.IcosahedronGeometry(r);
      return icosahedron;
    }
    /* 创建漫反射材质 
     * color: 材质颜色
     * wireframe: boolean 几何渲染线框 默认false
     * opacity: 0 - 1 透明度
     * transparent: boolean 是否开启透明 默认false
     *
     */
    function createMaterial(config = {
      color: 0x0000ff
    }) {
      return new THREE.MeshLambertMaterial(config);
    }

    /**
     * 创建高光材质
     */
    function createPhongMaterialMesh(config = {
      color: 0x0000ff,
      specular: 0x4488ee,
      shininess: 12
    }) {
      return new THREE.MeshPhongMaterial(config);
    }

    /* 创建网格 */
    function createMesh(geometry, materiall) {
      return new THREE.Mesh(geometry, materiall);
    }
  </script>
</body>

</html>